<template>
  <div class="app-container">
    <el-card shadow="never">
      <template #header>
        <div class="card-header">
          <h3>批量排班</h3>
        </div>
      </template>
      
      <el-form 
        ref="formRef" 
        :model="form" 
        :rules="rules" 
        label-width="100px" 
        v-loading="loading"
      >
        <!-- 医生信息 -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="科室" prop="departmentId">
              <el-select 
                v-model="form.departmentId" 
                placeholder="请选择科室" 
                style="width: 100%"
                @change="handleDepartmentChange"
              >
                <el-option 
                  v-for="item in departments" 
                  :key="item._id" 
                  :label="item.name" 
                  :value="item._id" 
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="医生" prop="doctorId">
              <el-select 
                v-model="form.doctorId" 
                placeholder="请选择医生" 
                style="width: 100%"
                filterable
              >
                <el-option 
                  v-for="item in doctors" 
                  :key="item._id" 
                  :label="`${item.name} (${item.title || '医生'})`" 
                  :value="item._id" 
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        
        <!-- 排班信息 -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="日期范围" prop="dateRange">
              <el-date-picker
                v-model="form.dateRange"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="YYYY-MM-DD"
                :disabled-date="disabledDate"
                style="width: 100%"
                :shortcuts="dateShortcuts"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="工作日" prop="workDays">
              <el-select 
                v-model="form.workDays" 
                multiple 
                placeholder="请选择工作日" 
                style="width: 100%"
              >
                <el-option label="周一" :value="1" />
                <el-option label="周二" :value="2" />
                <el-option label="周三" :value="3" />
                <el-option label="周四" :value="4" />
                <el-option label="周五" :value="5" />
                <el-option label="周六" :value="6" />
                <el-option label="周日" :value="0" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="最大预约数" prop="maxAppointments">
              <el-input-number
                v-model="form.maxAppointments"
                :min="0"
                :max="100"
                placeholder="不填则无限制"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-form-item label="时间段" prop="timeSlots">
          <div class="time-slots-container">
            <el-checkbox-group v-model="form.timeSlots">
              <el-checkbox-button 
                v-for="slot in timeSlotOptions" 
                :key="slot.value" 
                :label="slot.value"
              >
                {{ slot.label }}
              </el-checkbox-button>
            </el-checkbox-group>
          </div>
          <div class="form-tips">
            选择医生在选定日期内可出诊的时间段
          </div>
        </el-form-item>
        
        <el-form-item label="备注" prop="notes">
          <el-input 
            v-model="form.notes" 
            type="textarea" 
            placeholder="请输入备注信息（可选）" 
            :rows="3"
          />
        </el-form-item>
        
        <!-- 生成预览 -->
        <el-form-item>
          <el-button type="primary" @click="generatePreview" :loading="previewLoading">生成预览</el-button>
        </el-form-item>
        
        <!-- 预览表格 -->
        <div v-if="previewData.length > 0" class="preview-container">
          <h4>排班预览 (共 {{ previewData.length }} 天)</h4>
          <el-table
            :data="previewData"
            style="width: 100%"
            border
            max-height="400"
            stripe
          >
            <el-table-column prop="date" label="日期" width="120">
              <template #default="scope">
                {{ scope.row.date }}
                <span class="text-secondary">({{ getWeekdayName(scope.row.weekday) }})</span>
              </template>
            </el-table-column>
            <el-table-column label="时间段" min-width="200">
              <template #default="scope">
                <el-tag 
                  v-for="slot in scope.row.timeSlots" 
                  :key="slot" 
                  class="tag-item"
                  type="info"
                >
                  {{ slot }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="maxAppointments" label="最大预约数" width="120">
              <template #default="scope">
                {{ scope.row.maxAppointments || '不限' }}
              </template>
            </el-table-column>
            <el-table-column label="操作" width="100" align="center">
              <template #default="scope">
                <el-button 
                  link 
                  type="danger" 
                  @click="removePreviewItem(scope.$index)"
                >
                  移除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          
          <!-- 提交按钮 -->
          <div class="submit-container">
            <el-button type="success" @click="submitForm" :loading="submitLoading" :disabled="previewData.length === 0">
              提交批量排班
            </el-button>
            <el-button @click="resetPreview">重置预览</el-button>
            <el-button @click="goBack">取消</el-button>
          </div>
        </div>
      </el-form>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { scheduleAPI, departmentAPI, doctorAPI } from '@/utils/api'

// 路由实例
const router = useRouter()

// 加载状态
const loading = ref(false)
const previewLoading = ref(false)
const submitLoading = ref(false)

// 表单引用
const formRef = ref(null)

// 表单数据
const form = reactive({
  departmentId: '',
  doctorId: '',
  dateRange: [],
  workDays: [1, 2, 3, 4, 5],  // 默认选择周一到周五
  timeSlots: [],
  maxAppointments: undefined,
  notes: ''
})

// 预览数据
const previewData = ref([])

// 选项数据
const departments = ref([])
const doctors = ref([])

// 时间段选项
const timeSlotOptions = [
  { label: '08:00-09:00', value: '08:00-09:00' },
  { label: '09:00-10:00', value: '09:00-10:00' },
  { label: '10:00-11:00', value: '10:00-11:00' },
  { label: '11:00-12:00', value: '11:00-12:00' },
  { label: '14:00-15:00', value: '14:00-15:00' },
  { label: '15:00-16:00', value: '15:00-16:00' },
  { label: '16:00-17:00', value: '16:00-17:00' },
  { label: '17:00-18:00', value: '17:00-18:00' }
]

// 日期快捷选项
const dateShortcuts = [
  {
    text: '下周',
    value: () => {
      const now = new Date()
      const start = new Date()
      start.setTime(now.getTime() + 3600 * 1000 * 24 * (7 - now.getDay() + 1))
      const end = new Date()
      end.setTime(start.getTime() + 3600 * 1000 * 24 * 6)
      return [start, end]
    },
  },
  {
    text: '下两周',
    value: () => {
      const now = new Date()
      const start = new Date()
      start.setTime(now.getTime() + 3600 * 1000 * 24 * (7 - now.getDay() + 1))
      const end = new Date()
      end.setTime(start.getTime() + 3600 * 1000 * 24 * 13)
      return [start, end]
    },
  },
  {
    text: '本月剩余',
    value: () => {
      const now = new Date()
      const start = new Date(now.getTime() + 24 * 60 * 60 * 1000)
      const end = new Date(now.getFullYear(), now.getMonth() + 1, 0)
      return [start, end]
    },
  },
]

// 表单验证规则
const rules = {
  departmentId: [
    { required: true, message: '请选择科室', trigger: 'change' }
  ],
  doctorId: [
    { required: true, message: '请选择医生', trigger: 'change' }
  ],
  dateRange: [
    { required: true, message: '请选择日期范围', trigger: 'change' }
  ],
  workDays: [
    { required: true, message: '请选择工作日', trigger: 'change' }
  ],
  timeSlots: [
    { required: true, message: '请至少选择一个时间段', trigger: 'change' }
  ]
}

// 禁用的日期（今天之前的日期不可选）
const disabledDate = (time) => {
  return time.getTime() < Date.now() - 8.64e7 // 禁用今天之前的日期
}

// 获取星期几名称
const getWeekdayName = (weekday) => {
  const weekdayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return weekdayNames[weekday]
}

// 处理科室选择变化
const handleDepartmentChange = async () => {
  form.doctorId = ''
  doctors.value = []
  
  if (!form.departmentId) return
  
  try {
    const res = await doctorAPI.getDoctors({ departmentId: form.departmentId })
    doctors.value = res.data.items
  } catch (error) {
    console.error('获取医生列表失败', error)
    ElMessage.error('获取医生列表失败')
  }
}

// 获取科室列表
const getDepartments = async () => {
  try {
    const res = await departmentAPI.getDepartments()
    departments.value = res.data.items
  } catch (error) {
    console.error('获取科室列表失败', error)
    ElMessage.error('获取科室列表失败')
  }
}

// 生成预览数据
const generatePreview = async () => {
  formRef.value.validate(async (valid) => {
    if (valid) {
      previewLoading.value = true
      try {
        if (!form.dateRange || form.dateRange.length !== 2) {
          ElMessage.warning('请选择有效的日期范围')
          return
        }
        
        const startDate = new Date(form.dateRange[0])
        const endDate = new Date(form.dateRange[1])
        const workDays = form.workDays.map(day => Number(day))
        
        // 生成日期数组
        const tempPreviewData = []
        
        for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
          const weekday = d.getDay()
          
          // 检查是否是选定的工作日
          if (workDays.includes(weekday)) {
            tempPreviewData.push({
              date: d.toISOString().split('T')[0],
              weekday,
              timeSlots: [...form.timeSlots],
              maxAppointments: form.maxAppointments
            })
          }
        }
        
        // 检查是否有冲突的排班
        await checkScheduleConflicts(tempPreviewData)
        
        previewData.value = tempPreviewData
        
        if (previewData.value.length === 0) {
          ElMessage.warning('所选日期范围内没有符合条件的工作日')
        }
      } catch (error) {
        console.error('生成预览失败', error)
        ElMessage.error('生成预览失败')
      } finally {
        previewLoading.value = false
      }
    }
  })
}

// 检查排班冲突
const checkScheduleConflicts = async (previewItems) => {
  try {
    // 获取日期范围内该医生的所有排班
    const params = {
      doctorId: form.doctorId,
      startDate: form.dateRange[0],
      endDate: form.dateRange[1]
    }
    
    const res = await scheduleAPI.getSchedules(params)
    const existingSchedules = res.data.items || []
    
    if (existingSchedules.length === 0) return
    
    // 检查冲突
    for (let i = 0; i < previewItems.length; i++) {
      const previewItem = previewItems[i]
      
      // 查找同一天的排班
      const sameDay = existingSchedules.find(s => s.date === previewItem.date)
      
      if (sameDay) {
        const existingSlots = sameDay.timeSlots || []
        
        // 检查时间段冲突
        const conflictSlots = previewItem.timeSlots.filter(slot => existingSlots.includes(slot))
        
        if (conflictSlots.length > 0) {
          // 弹窗提示用户
          const result = await ElMessageBox.confirm(
            `${previewItem.date} (${getWeekdayName(previewItem.weekday)}) 已有排班，以下时间段有冲突：${conflictSlots.join('、')}。是否从预览中移除该日期?`,
            '排班冲突提示',
            {
              confirmButtonText: '移除冲突日期',
              cancelButtonText: '保留但移除冲突时段',
              type: 'warning'
            }
          ).catch(() => 'remove_slots')
          
          if (result === 'confirm') {
            // 移除整个日期
            previewItems.splice(i, 1)
            i--
          } else {
            // 只移除冲突的时间段
            previewItem.timeSlots = previewItem.timeSlots.filter(slot => !conflictSlots.includes(slot))
            
            // 如果没有剩余时间段，移除整个日期
            if (previewItem.timeSlots.length === 0) {
              previewItems.splice(i, 1)
              i--
            }
          }
        }
      }
    }
  } catch (error) {
    console.error('检查排班冲突失败', error)
    ElMessage.error('检查排班冲突失败')
  }
}

// 从预览中移除项目
const removePreviewItem = (index) => {
  previewData.value.splice(index, 1)
}

// 重置预览
const resetPreview = () => {
  previewData.value = []
}

// 提交表单
const submitForm = async () => {
  if (previewData.value.length === 0) {
    ElMessage.warning('没有可提交的排班数据')
    return
  }
  
  submitLoading.value = true
  try {
    // 准备批量创建数据
    const batchData = {
      doctorId: form.doctorId,
      departmentId: form.departmentId,
      schedules: previewData.value.map(item => ({
        date: item.date,
        timeSlots: item.timeSlots,
        maxAppointments: item.maxAppointments,
        notes: form.notes
      }))
    }
    
    await scheduleAPI.batchCreateSchedules(batchData)
    ElMessage.success(`成功创建 ${previewData.value.length} 天排班`)
    
    // 返回列表页
    router.push('/schedules/list')
  } catch (error) {
    console.error('批量创建排班失败', error)
    ElMessage.error(error.response?.data?.message || '批量创建排班失败')
  } finally {
    submitLoading.value = false
  }
}

// 返回上一页
const goBack = () => {
  router.go(-1)
}

// 页面加载时获取数据
onMounted(async () => {
  await getDepartments()
})
</script>

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.time-slots-container {
  margin-bottom: 10px;
}

.form-tips {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.preview-container {
  margin-top: 30px;
  border-top: 1px dashed #dcdfe6;
  padding-top: 20px;
}

.preview-container h4 {
  margin-bottom: 15px;
  color: #303133;
}

.text-secondary {
  font-size: 12px;
  color: #909399;
}

.tag-item {
  margin-right: 4px;
  margin-bottom: 4px;
}

.submit-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  gap: 10px;
}
</style> 